#pragma once

#include <functional>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include "effect.h"
#include "irblock.h"
#include "iroperand.h"

struct IRFunction {
    std::string name;
    IRBlock* entry;
    IRBlock* exit;
    IR::Operand* ret;
    std::vector<IR::Variable*> args;

    std::unordered_map<std::string, IR::Variable> usedGlobalVars;
    SideEffect globalEffects;
    std::vector<int> argMemEffects;

    bool IsExternal() const { return !entry; }

    void Simplify();
    void SetParent();
    void Validate();

    void AnalEffects();
};

struct IRModule {
    std::unordered_map<IR::Variable*, Symbol*> globalVars;
    std::unordered_map<std::string, IRFunction*> funcs;
    std::vector<IRFunction*> globalFuncs;
};
